/**
 * GenJ - GenealogyJ
 *
 * Copyright (C) 1997 - 2002 Nils Meier <nils@meiers.net>
 *
 * This piece of code is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of the
 * License, or (at your option) any later version.
 *
 * This code is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
package genj.gedcom;

/**
 * Gedcom Property : SEX
 */
public class PropertySex extends Property {

    /** images */

    /** txts */
    public final static String TXT_SEX = Gedcom.getResources().getString("prop.sex"),
	    TXT_MALE = Gedcom.getResources().getString("prop.sex.male"), TXT_FEMALE = Gedcom
		    .getResources().getString("prop.sex.female"), TXT_UNKNOWN = Gedcom
		    .getResources().getString("prop.sex.unknown");

    /** sexes */
    public static final int UNKNOWN = 0;
    public static final int MALE = 1;
    public static final int FEMALE = 2;

    /** the sex code */
    private int sex = UNKNOWN;

    /** the sex as string (unknown code) */
    private String sexAsString;

    /**
     * need tag-argument constructor for all properties
     */
    /* package */PropertySex(String tag) {
	super(tag);
	assertTag("SEX");
    }

    /* package */PropertySex() {
	super("SEX");
    }

    /**
     * Returns <b>true</b> if this property is valid
     */
    @Override
    public boolean isValid() {
	return (sexAsString == null);
    }

    /**
     * Returns localized label for sex of male/female
     */
    static public String getLabelForSex(int which) {
	switch (which) {
	case MALE:
	    return Gedcom.getResources().getString("prop.sex.male");
	case FEMALE:
	    return Gedcom.getResources().getString("prop.sex.female");
	default:
	    return Gedcom.getResources().getString("prop.sex.unknown");
	}
    }

    /**
     * Accessor for Sex
     */
    public int getSex() {
	return sex;
    }

    /**
     * Accessor for Value
     */
    @Override
    public String getValue() {
	if (sexAsString != null)
	    return sexAsString;
	if (sex == MALE)
	    return "M";
	if (sex == FEMALE)
	    return "F";
	return "";
    }

    /**
     * A value meant for display
     */
    @Override
    public String getDisplayValue() {
	return getLabelForSex(sex);
    }

    /**
     * Accessor for Sex
     */
    public void setSex(int newSex) {
	String old = getValue();
	sexAsString = null;
	sex = newSex;
	propagatePropertyChanged(this, old);
	// Done
    }

    /**
     * Accessor for Value
     */
    @Override
    public void setValue(String newValue) {

	String old = getValue();

	// Cannot parse anything longer than 1
	if (newValue.trim().length() > 1) {
	    sexAsString = newValue;
	} else {
	    // zero length -> unknown
	    if (newValue.length() == 0) {
		sexAsString = null;
		sex = UNKNOWN;
	    } else {
		// Female or Male ?
		switch (newValue.charAt(0)) {
		case 'f':
		case 'F':
		    sex = FEMALE;
		    sexAsString = null;
		    break;
		case 'm':
		case 'M':
		    sex = MALE;
		    sexAsString = null;
		    break;
		default:
		    sexAsString = newValue;
		    break;
		}
	    }
	}
	// notify
	propagatePropertyChanged(this, old);
	// done
    }

    /**
     * Tester for validity of sex
     */
    public static boolean isSex(int tst) {
	return tst == MALE || tst == FEMALE;
    }

    /**
     * Calculates opposite sex
     */
    public static int calcOppositeSex(int from, int fallback) {
	if (from == MALE)
	    return FEMALE;
	if (from == FEMALE)
	    return MALE;
	return fallback;
    }

    /**
     * Calculates opposite sex
     */
    public static int calcOppositeSex(Indi from, int fallback) {

	// Something to base calculation on?
	if (from == null) {
	    return fallback;
	}

	// Check other's sex
	return calcOppositeSex(from.getSex(), fallback);

    }
}
